#!/bin/bash

# 创建项目目录结构
mkdir -p project/include    # 存储头文件
mkdir -p project/src        # 存储源文件
mkdir -p project/data       # 存储数据文件
mkdir -p project/bin        # 存储可执行文件
mkdir -p project/obj        # 存储对象文件
mkdir -p project/img        # 存储图片 例如 README.md 的图片
mkdir -p project/log        # 存储日志文件

# 创建头文件并添加防止重复编译的宏
create_header() {
    local header_file=$1
    local header_guard=$(basename $header_file | tr '[:lower:]' '[:upper:]' | tr '.' '_')
    echo "#ifndef __${header_guard}__" > $header_file
    echo "#define __${header_guard}__" >> $header_file
    echo "" >> $header_file
    echo "// 引用头文件" >> $header_file
    echo "#include <ncurses.h>" >> $header_file
    echo "// 声明函数" >> $header_file
    echo "" >> $header_file
    echo "#endif // __${header_guard}__" >> $header_file
}

# 创建头文件
create_header "project/include/user.h"    # 用户相关结构体和函数声明的头文件
create_header "project/include/flight.h"  # 航班相关结构体和函数声明的头文件
create_header "project/include/list.h"    # 链表操作相关函数声明的头文件
create_header "project/include/dlist.h"   # 双向循环链表操作相关函数声明的头文件
create_header "project/include/array.h"   # 顺序表操作相关函数声明的头文件
create_header "project/include/utils.h"   # 公用工具函数声明的头文件
create_header "project/include/ui.h"      # 终端 UI 界面相关函数声明的头文件

# 创建源文件
touch project/src/main.c                  # 主程序入口文件
touch project/src/user.c                  # 用户功能实现的源文件
touch project/src/flight.c                # 航班功能实现的源文件
touch project/src/list.c                  # 单链表操作实现的源文件
touch project/src/dlist.c                 # 双向循环链表操作实现的源文件
touch project/src/array.c                 # 顺序表操作实现的源文件
touch project/src/utils.c                 # 公用工具函数实现的源文件
touch project/src/ui.c                    # 终端 UI 界面实现的源文件

# 创建项目说明文档
touch project/README.md                   # 项目说明文档

# 创建数据文件
touch project/data/flights.txt                  # 航班管理信息
touch project/data/admin_users.txt              # 管理员账户信息文件
touch project/data/regular_users.txt            # 普通用户信息文件
touch project/data/silver_members.txt           # 银卡会员信息文件(9折)
touch project/data/gold_members.txt             # 金卡会员信息文件(8折)
touch project/data/platinum_members.txt         # 白金会员信息文件(7折)

# 在每个 .c 文件中插入 #include "head.h"
add_include_to_c() {
    local c_file=$1
    echo '#include "head.h"' | cat - $c_file > temp && mv temp $c_file
}

# 在 main.c 中添加内容
cat > project/src/main.c <<EOL
#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("Hello, all students of HQYJ_24071!\n");
    return 0;
}
EOL

# 对每个 .c 文件应用
add_include_to_c "project/src/main.c"
add_include_to_c "project/src/user.c"
add_include_to_c "project/src/flight.c"
add_include_to_c "project/src/list.c"
add_include_to_c "project/src/dlist.c"
add_include_to_c "project/src/array.c"
add_include_to_c "project/src/utils.c"

# 创建并写入 head.h 文件
cat > project/include/head.h <<EOL
#ifndef __HEAD_H__
#define __HEAD_H__

// 导入项目头文件
#include "user.h"
#include "flight.h"
#include "list.h"
#include "dlist.h"
#include "array.h"
#include "utils.h"
#include "ui.h"

// 导入系统头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <ncurses.h>
#include <locale.h>
#include <wchar.h>
// 定义宏定义
#define LOG_FILE "log/error.log"                    // 报错日志文件
#define FLIGHTS_FILE "data/flights.txt"             // 航班信息文件

// 定义用户信息文件路径
#define ADMIN_FILE "data/admin_users.txt"           // 管理员账户信息文件
#define REGULAR_FILE "data/regular_users.txt"       // 普通用户信息文件
#define SILVER_FILE "data/silver_members.txt"       // 银卡会员信息文件(9折)
#define GOLD_FILE "data/gold_members.txt"           // 金卡会员信息文件(8折)
#define PLATINUM_FILE "data/platinum_members.txt"   // 白金会员信息文件(7折)

// 示例宏定义，可以用于获取折扣
#define SILVER_DISCOUNT 0.9                         // 银卡会员折扣(9折)
#define GOLD_DISCOUNT 0.8                           // 金卡会员折扣(8折)
#define PLATINUM_DISCOUNT 0.7                       // 白金会员折扣(7折)

// 错误输出宏定义，写入日志文件并显示在终端
#define ERRLOG(msg) do { \
    time_t now = time(NULL); \
    char *timestr = ctime(&now); \
    timestr[strlen(timestr) - 1] = '\0'; /* 去掉末尾的换行符 */ \
    FILE *log_file = fopen(LOG_FILE, "a"); \
    if (log_file) { \
        fprintf(log_file, "[%s] 错误: %s\t文件: %s\t函数: %s\t行号: %d\n\n", \
                timestr, msg, __FILE__, __func__, __LINE__); \
        fclose(log_file); \
    } else { \
        fprintf(stderr, "错误: 无法打开日志文件: %s\n", LOG_FILE); \
    } \
    /* 输出到标准错误流 */ \
    fprintf(stderr, "[%s] 错误: %s\t文件: %s\t函数: %s\t行号: %d\n", \
            timestr, msg, __FILE__, __func__, __LINE__); \
} while (0)

#endif
EOL

# 产生 Makefile 文件
cat > project/Makefile <<EOL
# 编译器
CC = gcc

# 编译选项
CFLAGS = -Wall -g -I./include
LDFLAGS = -lncurses

# 目标文件
TARGET = ./bin/HQYJ_flight_system
LDFLAGS = -lncursesw
# -lncurses 

# 源文件目录和对象文件目录
SRC_DIR = ./src
OBJ_DIR = ./obj

# 源文件和对应的对象文件
SRCS = \$(wildcard \$(SRC_DIR)/*.c)
OBJS = \$(patsubst \$(SRC_DIR)/%.c, \$(OBJ_DIR)/%.o, \$(SRCS))

# 目标: 生成可执行文件
\$(TARGET): \$(OBJS)
	@mkdir -p \$(dir \$@)  # 确保目标目录存在
	\$(CC) \$(OBJS) -o \$@ \$(LDFLAGS)

# 生成对象文件
\$(OBJ_DIR)/%.o: \$(SRC_DIR)/%.c
	@mkdir -p \$(OBJ_DIR)  # 确保对象文件目录存在
	\$(CC) \$(CFLAGS) -c \$< -o \$@

# 清理目标
.PHONY: clean
clean:
	rm -f \$(OBJ_DIR)/*.o \$(TARGET)

EOL
